#include <fstream>
#include "direct_io_strategy.h"
#include "gtest/gtest.h"

namespace Base {
namespace SystemLog {
namespace {
constexpr const char* TEST_LOG_DIR = "out/tests/logs";
constexpr const char* TEST_MESSAGE = "Hello, Direct IO!\n";
constexpr const char TEST_CHAR = 't';
constexpr size_t TEST_DIRECT_IO_ALIGNMENT = 4096;
constexpr size_t TEST_DIRECT_IO_DATA_SIZE = 4096;
constexpr size_t TEST_DIRECT_IO_BUFFER_SIZE = 8192;

std::string ReadFileContent(const std::string &path) {
    std::ifstream file(path);
    if (!file.is_open()) {
        return "";
    }
    return std::string((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
}
} // namespace

class DirectIOStrategyTest : public testing::Test {
public:
    static void SetUpTestCase(void);
    static void TearDownTestCase(void);
    void SetUp();
    void TearDown();
};

void DirectIOStrategyTest::SetUpTestCase(void)
{}

void DirectIOStrategyTest::TearDownTestCase(void)
{}

void DirectIOStrategyTest::SetUp(void)
{}

void DirectIOStrategyTest::TearDown(void)
{}

/**
 * @tc.name: DirectIOStrategyTest_001
 * @tc.desc: verify Write function.
 * @tc.type: FUNC
 */
TEST_F(DirectIOStrategyTest, DirectIOStrategyTest_001)
{
    DirectIOOptions options;
    options.filePathPattern = std::string(TEST_LOG_DIR) + "/directio.log";
    options.alignment = TEST_DIRECT_IO_ALIGNMENT;
    options.bufferSize = TEST_DIRECT_IO_BUFFER_SIZE;
    DirectIOStrategy dioStrategy(options);

    std::vector<char> alignedData(TEST_DIRECT_IO_DATA_SIZE, TEST_CHAR);
    ASSERT_EQ(dioStrategy.Write(alignedData.data(), TEST_DIRECT_IO_DATA_SIZE), ERR_OK);
    ASSERT_EQ(dioStrategy.Flush(), ERR_OK);
    ASSERT_EQ(dioStrategy.Close(), ERR_OK);
    
    auto content = ReadFileContent(options.filePathPattern);
    ASSERT_EQ(content.size(), TEST_DIRECT_IO_DATA_SIZE);
    ASSERT_EQ(content, std::string(TEST_DIRECT_IO_DATA_SIZE, TEST_CHAR));
}
} // namespace SystemLog
} // namespace Base
